package com.september.afterclient;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.ws.rs.core.MediaType;

import com.google.gson.Gson;
import com.september.mongo.entities.User;
import com.september.prop.Properteer;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;

public class AfterClient {

	private String path;
	private Properties prop;
	private Client client;
	
	public AfterClient() {
		prop = Properteer.getInstance().Properties() ;
		path = prop.getProperty("HOST")+prop.getProperty("ROOT_PATH");
		client = Client.create();
		
	}
	
	public <T> List<T> getAllEntity(Class<T> entityClass) {
		String requestPath = prop.getProperty("GET");
		requestPath = requestPath.replace("{entity}",entityClass.getName());
		WebResource webResource = client
				   .resource(path+requestPath);
		ClientResponse response = webResource.type(MediaType.TEXT_XML).get(ClientResponse.class);
		//Properteer.getInstance().getLogger(this.getClass()).debug(response.getEntity(String.class));
		
		if (response.getStatus() != 200) {
			Properteer.getInstance().getLogger(this.getClass()).debug("Failed : HTTP error code : " + response.getStatus());
			return null;
		}
		
		
			Gson gson = new Gson();
			String result = response.getEntity(String.class);
			List<T> outList = new LinkedList<T>();
			return gson.fromJson(result, outList.getClass());
		
		
		
	}
	
	public <T> T getEntity(Class<T> entityClass, String id) {
		String requestPath = prop.getProperty("GET_BY_ID");
		requestPath = requestPath.replace("{entity}", entityClass.getName()).replace("{id}", id);
		WebResource webResource = client
				   .resource(path+requestPath);
		ClientResponse response = webResource.type(MediaType.TEXT_XML).get(ClientResponse.class);
		//Properteer.getInstance().getLogger(this.getClass()).debug(response.getEntity(String.class));
		
		if (response.getStatus() != 200) {
			Properteer.getInstance().getLogger(this.getClass()).debug("Failed : HTTP error code : " + response.getStatus());
			return null;
		}
		
		
			Gson gson = new Gson();
			String result = response.getEntity(String.class);
			return gson.fromJson(result, entityClass);
		
		
		
	}
	
	public <T,S> List<T> getEntityByRef(Class<T> entityClass,Class<S> refClass, String refField, String refValue) {
		String requestPath = prop.getProperty("GET_BY_REF");
		//{entity}/{reference}/{referenceField}/{value}
		requestPath = requestPath.replace("{entity}", entityClass.getName()).replace("{reference}", refClass.getName()).replace("{referenceField}", refField).replace("{value}", refValue);
		WebResource webResource = client
				   .resource(path+requestPath);
		ClientResponse response = webResource.type(MediaType.TEXT_XML).get(ClientResponse.class);
		//Properteer.getInstance().getLogger(this.getClass()).debug(response.getEntity(String.class));
		
		if (response.getStatus() != 200) {
			Properteer.getInstance().getLogger(this.getClass()).debug("Failed : HTTP error code : " + response.getStatus());
			return null;
		}
		
		
			Gson gson = new Gson();
			List<T> outList = new LinkedList<T>();
			String result = response.getEntity(String.class);
			return (List<T>) gson.fromJson(result, outList.getClass());
		
		
		
	}
	
	public <T> Boolean delete(Class<T> entityClass, String id) {
		String requestPath = prop.getProperty("DELETE_BY_ID");
		//delete/{entity}/{id}
		requestPath = requestPath.replace("{entity}", entityClass.getName()).replace("{id}", id);
		WebResource webResource = client
				   .resource(path+requestPath);
		ClientResponse response = webResource.type(MediaType.TEXT_XML).get(ClientResponse.class);
		//Properteer.getInstance().getLogger(this.getClass()).debug(response.getEntity(String.class));
		
		if (response.getStatus() != 200) {
			Properteer.getInstance().getLogger(this.getClass()).debug("Failed : HTTP error code : " + response.getStatus());
			return null;
		}
		
		
			Gson gson = new Gson();
			String result = response.getEntity(String.class);
			return  gson.fromJson(result, Boolean.class);
		
		
		
	}
	
	public <T> Boolean saveEntity(T entity) {
		
		String requestPath = prop.getProperty("SAVE");
		//save/{entity}
		requestPath = requestPath.replace("{entity}", entity.getClass().getName());
		WebResource webResource = client
				   .resource(path+requestPath);
		Gson gson = new Gson();
		String jsonized = gson.toJson(entity);
		ClientResponse response = webResource.type(MediaType.APPLICATION_JSON).post(ClientResponse.class, jsonized);
		//Properteer.getInstance().getLogger(this.getClass()).debug(response.getEntity(String.class));
		
		if (response.getStatus() != 201) {
			Properteer.getInstance().getLogger(this.getClass()).debug("Failed : HTTP error code : " + response.getStatus());
			return null;
		}
		
		
			//Gson gson = new Gson();
			String result = response.getEntity(String.class);
			return  gson.fromJson(result, Boolean.class);
		
	}
	
	
	public <T> Boolean updateEntity(Class<T> entityClass, String id, T entityUpdated) {
		
		String requestPath = prop.getProperty("UPDATE_BY_ID");
		//update/{entity},{id}
		requestPath = requestPath.replace("{entity}", entityClass.getName()).replace("{id}", id);
		WebResource webResource = client
				   .resource(path+requestPath);
		Gson gson = new Gson();
		String jsonized = gson.toJson(entityUpdated);
		Map<String,Object> jsonUpdate = gson.fromJson(jsonized, HashMap.class);
//		Field[] fields = entityClass.getDeclaredFields();
//		for(Field field:fields) {
//			Annotation[] anns = field.getAnnotations();
//			for(Annotation ann:anns) {
//				if(ann.annotationType().equals(com.google.code.morphia.annotations.Id.class)) {
//					jsonUpdate.remove(field.getName());
//				}
//			}
//		}
		ClientResponse response = webResource.type(MediaType.APPLICATION_JSON).post(ClientResponse.class,  gson.toJson(jsonUpdate));
		//Properteer.getInstance().getLogger(this.getClass()).debug(response.getEntity(String.class));
		
		if (response.getStatus() != 201) {
			Properteer.getInstance().getLogger(this.getClass()).debug("Failed : HTTP error code : " + response.getStatus());
			return null;
		}
		
		
			//Gson gson = new Gson();
			String result = response.getEntity(String.class);
			return  gson.fromJson(result, Boolean.class);
		
	}
	
}
